/*
  (C) 2007 - Boston University
  Contact: Michael Ocean 

	This class is taken directly from a CS511 submission

  This work is a part of the larger snBench project.  Information
  can be found at: http://csr.bu.edu/snbench 

  This program is free software; you can redistribute it and/or
  modify it under the terms of Version 2 of the GNU General Public 
  License.
  
  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  General Public License for more details.
  
  You should have received a copy of the GNU Library General Public
  License along with this library; if not, write to the Free
  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
package stepide.opcodes;

import java.util.Hashtable;
import java.util.Collection;
import java.util.Enumeration;

/**
 * Overview: TypeSignature contains all type information for a specific STEP opcode,
 * including information about overloading.  The information held by this class
 * follows from the opcode xsd schema contained in the same directory of this
 * class file.
 */

public class TypeSignature {
	private int id;
	private boolean allowInfinite;
	private String outputType;
	private Hashtable<Integer, String> inputTypes;
	
	/**
	 * Constructs a TypeSignature with all type and overload info defined
	 * @param id The unique identified contained within the <typesig> XML tag
	 * @param allowInfinite true if the last of the input parameters can be used an infinite number of times
	 * @param outputType snBench type of the opcode's output
	 * @param inputTypes contains a mapping of an input's arguement index and its snBench type
	 * @exception  IllegalArgumentException  if the output/inputTypes are null, inputTypes is empty, or id < 1
	 */
	TypeSignature(int id, boolean allowInfinite, String outputType, Hashtable<Integer, String> inputTypes) {
		if( (id < 1) || (outputType) == null || (inputTypes == null) || (inputTypes.isEmpty() == true) ) {
			throw new IllegalArgumentException("An input param is either null, id is < 1, or the Hashtable is empty.");
		}
		
		this.id = id;
		this.allowInfinite = allowInfinite;
		this.outputType = outputType;
		this.inputTypes = inputTypes;
	}
	
	/**
	 * @return the unique identifer associated with the <typeside> tag
	 */
	public int getId() { return id; }
	
	/**
	 * @return true if the last input type can be used an infinite number of times
	 */
	public boolean getAllowInfinite() { return allowInfinite; }
	
	/**
	 * @return the the snBench type of the opcode's output
	 */
	public String getOutputType() {return outputType; }
	
	/**
	 * @return A collection containing all of the snBench input types
	 */
	public Collection<String> getInputTypes() { return inputTypes.values(); }

	/**
	 * @return A string representation of all type sig information
	 */
	public String toString() {
		String inputs = "";
		//need to do this since we need to display arg # and we store arg # == key
		for (Enumeration e = inputTypes.keys(); e.hasMoreElements() ;) {
			Integer key = (Integer) e.nextElement();
			inputs += "Input: argument # " + key.toString() + " type: " + inputTypes.get(key)  + "\n";			
     	}

		return "\nType Signature ID: " + ((Integer)getId()).toString() + "\n" + 
			"Allow Infinite: " + ((Boolean)getAllowInfinite()).toString() + "\n" +  
			"Output type: " + getOutputType() + "\n" + inputs;
	}
}